feat: add MiniMax as first-class provider with M2.7 models and native thinking support#2155
feat: add MiniMax as first-class provider with M2.7 models and native thinking support#2155octo-patch wants to merge 3 commits intorouter-for-me:mainfrom
Conversation
Add comprehensive MiniMax provider integration: - Register MiniMax-M2.5 and MiniMax-M2.5-highspeed models in the model registry with 204K context length and thinking capability metadata - Create dedicated MiniMax thinking provider that handles the native reasoning_split boolean toggle format, converting from budget/level modes to on/off semantics - Enhance ApplyThinking to prefer provider-key-specific thinking appliers over generic format appliers, enabling MiniMax (and future providers) to work correctly when configured through openai-compatibility - Add MiniMax thinking config extraction with fallback to OpenAI format - Add MiniMax to thinking config stripping for non-thinking models - Add MiniMax constant to provider identifiers - Add MiniMax configuration example in config.example.yaml showing setup via openai-compatibility with base URL and model definitions - Update README.md and README_CN.md with MiniMax support documentation
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request integrates MiniMax as a first-class provider into the CLIProxyAPI, allowing users to leverage MiniMax models with native thinking capabilities through an OpenAI-compatible configuration. The core of the change involves adapting the system to MiniMax's unique Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request adds support for the MiniMax provider, allowing users to leverage MiniMax models through the OpenAI-compatible configuration. The changes include adding MiniMax to the model registry, creating a dedicated thinking provider to handle MiniMax's native reasoning_split parameter, and enhancing the thinking application logic to prioritize provider-specific handlers. My review focuses on improving the implementation of the new MiniMax thinking provider for better clarity and maintainability. The overall implementation is solid and well-designed to accommodate providers with custom thinking formats.
| if thinking.IsUserDefinedModel(modelInfo) { | ||
| return applyMiniMax(body, config), nil | ||
| } | ||
| if modelInfo.Thinking == nil { | ||
| return body, nil | ||
| } | ||
|
|
||
| return applyMiniMax(body, config), nil |
There was a problem hiding this comment.
The logic in this Apply function can be simplified. The current structure with multiple if statements and return points can be condensed into a single conditional check, which improves readability and reduces complexity.
if !thinking.IsUserDefinedModel(modelInfo) && modelInfo.Thinking == nil {
return body, nil
}
return applyMiniMax(body, config), nilThere was a problem hiding this comment.
Thanks for the suggestion! Simplified the conditionals into a single check in 3e4482c.
| reasoningSplit := configToBoolean(config) | ||
|
|
||
| if len(body) == 0 || !gjson.ValidBytes(body) { | ||
| body = []byte(`{}`) | ||
| } | ||
|
|
||
| // Remove any OpenAI-style reasoning_effort that may have been set | ||
| result, _ := sjson.DeleteBytes(body, "reasoning_effort") | ||
| result, _ = sjson.SetBytes(result, "reasoning_split", reasoningSplit) | ||
|
|
||
| return result |
There was a problem hiding this comment.
The applyMiniMax function can be refactored for better clarity by reusing the body variable instead of introducing a new result variable. This makes the data flow more straightforward and the code more concise.
reasoningSplit := configToBoolean(config)
if len(body) == 0 || !gjson.ValidBytes(body) {
body = []byte(`{}`)
}
// Remove any OpenAI-style reasoning_effort that may have been set
body, _ = sjson.DeleteBytes(body, "reasoning_effort")
body, _ = sjson.SetBytes(body, "reasoning_split", reasoningSplit)
return bodyThere was a problem hiding this comment.
Good catch — refactored to reuse body directly in 3e4482c.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 63981af3cf
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| "max_completion_tokens": 32768 | ||
| } | ||
| ], | ||
| "minimax": [ |
There was a problem hiding this comment.
Register MiniMax in static model registry
Adding a minimax section in models.json is not sufficient because internal/registry/model_definitions.go still does not define or traverse a minimax field in staticModelsJSON, GetStaticModelDefinitionsByChannel, or LookupStaticModelInfo; the new entries are therefore dropped on unmarshal and never found by lookup. In practice, LookupModelInfo(model, "minimax") returns nil for these models, so MiniMax requests are treated as user-defined and bypass the capability metadata/validation this commit is trying to introduce.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Great catch! Fixed in 3e4482c — added MiniMax field to staticModelsJSON, GetMiniMaxModels() getter, case "minimax" in GetStaticModelDefinitionsByChannel, and data.MiniMax to LookupStaticModelInfo.
Address review feedback: - Register MiniMax in staticModelsJSON struct, GetStaticModelDefinitionsByChannel, and LookupStaticModelInfo so model entries are properly unmarshalled and found - Simplify Apply() by condensing two conditionals into one - Reuse body variable in applyMiniMax() instead of introducing result Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3e4482c543
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if hasThinkingConfig(config) { | ||
| return config | ||
| } | ||
| return extractOpenAIConfig(body) |
There was a problem hiding this comment.
Parse OpenAI Responses thinking for MiniMax
The MiniMax branch only falls back to extractOpenAIConfig, which reads reasoning_effort, but OpenAI Responses requests use reasoning.effort (the openai-response shape used by /responses/compact in OpenAICompatExecutor.Execute). In that path, extractThinkingConfig returns empty, hasThinkingConfig is false, and the MiniMax applier is never invoked, so reasoning_split is not produced and MiniMax-specific thinking support silently does nothing for responses traffic.
Useful? React with 👍 / 👎.
luispater
left a comment
There was a problem hiding this comment.
Summary
This adds MiniMax model definitions and a provider-specific thinking applier, but I found one blocking gap in the thinking pipeline.
Blocking
OpenAICompatExecutorstill switches/responses/compactrequests to theopenai-responsewire format, where thinking is represented asreasoning.effort. The new MiniMax path only extracts/strips/appliesreasoning_splitand top-levelreasoning_effort, andApplyThinkingnow rewrites the target format from the wire format to the provider key before extraction. As a result, MiniMax requests on/responses/compacteither skip thinking conversion entirely or can retain a stalereasoning.effortfield whenreasoning_splitis added.
Non-blocking
- Inference from
internal/registry/model_updater.go: the remote catalog refresh path still omitsminimaxfromdetectChangedProvidersandvalidateModelsCatalog. That means MiniMax changes will not trigger refresh callbacks, and a fetched catalog without aminimaxsection would still be accepted. - I did not see test coverage for the new provider-key override path or the MiniMax applier. Please add at least one
ApplyThinkingcase for OpenAI chat input, one foropenai-response, and one static catalog load/lookup case.
Test plan
- Not run locally per request.
gh pr checks 2155reported no checks on March 16, 2026.
Add MiniMax-M2.7 and MiniMax-M2.7-highspeed to the static model registry. M2.7 offers 1M token context window (up from 204K on M2.5) with 8K max output tokens and full reasoning_split thinking support. Existing M2.5 models are retained for backward compatibility.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fa55e2fa26
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if providerKey != providerFormat { | ||
| if keyApplier := GetProviderApplier(providerKey); keyApplier != nil { | ||
| applier = keyApplier | ||
| providerFormat = providerKey |
There was a problem hiding this comment.
Reuse static MiniMax metadata for compat models
When MiniMax is configured through the new openai-compatibility example, sdk/cliproxy/service.go:955-970 still registers compat.Models as UserDefined: true without copying any Thinking support, and registry.LookupModelInfo prefers that dynamic entry over the static minimax definitions (internal/registry/model_registry.go:173-176). So this new provider-key override still sends MiniMax-M2.7 down the applyUserDefinedModel path, meaning the levels/capabilities added in models.json are never used for the advertised config path and MiniMax requests keep bypassing validation/clamping.
Useful? React with 👍 / 👎.
| // Remove any OpenAI-style reasoning_effort that may have been set | ||
| body, _ = sjson.DeleteBytes(body, "reasoning_effort") | ||
| body, _ = sjson.SetBytes(body, "reasoning_split", reasoningSplit) |
There was a problem hiding this comment.
Drop Responses reasoning fields before setting reasoning_split
/responses/compact traffic stays in the openai-response schema, and the translator returns the raw payload when source and target are both openai-response (sdk/translator/registry.go:43-52). For requests that reach this applier via a thinking suffix, an existing reasoning.effort object therefore survives because this code only deletes top-level reasoning_effort. The forwarded MiniMax request can end up carrying both reasoning_split and the stale OpenAI Responses reasoning block, which is a schema mismatch specific to compact/Responses callers.
Useful? React with 👍 / 👎.
|
Thanks for the thorough review @luispater! You're right about the thinking pipeline gap with the I'll update the PR to handle the |
Summary
reasoning_splitthinking mode support for all MiniMax modelsModels Added
Test Plan